package ink.tsg.elasticsearch.config;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import net.logstash.logback.encoder.org.apache.commons.lang.ArrayUtils;
import net.logstash.logback.encoder.org.apache.commons.lang.StringEscapeUtils;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.slf4j.MDC;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * @author geo_tsg
 * @version 1.0.0
 * @ClassName WebLogAspect.java
 * @Description
 * @createTime 2021-12-16
 */
@Aspect
@Order(1)
@Component
public class WebLogAspect {


    private Logger logger = LoggerFactory.getLogger(this.getClass());

//    ThreadLocal<LogTemplate> logJsonModel = new ThreadLocal<>();


    //定义项目请求拦截路径，一般是controller层
    @Pointcut("execution(* ink.tsg.elasticsearch.controller.*.*(..)))")
    public void webLog() {
    }



    @Before("webLog()")
    public void doBefore(JoinPoint joinPoint) throws Throwable {
        //封装请求入参日志对象
//        LogTemplate logTemplate = new LogTemplate();
//        logTemplate.setStartTime(LocalDateTime.now());
//        logTemplate.setResponseTime(System.currentTimeMillis());
//        // 接收到请求，记录请求内容
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();
//        // 记录下请求内容
//        logTemplate.setUrl(request.getRequestURL().toString());
//        //处理文件上传日志记录
//        Object[] args = joinPoint.getArgs();
//        Stream<?> stream = ArrayUtils.isEmpty(args) ? Stream.empty() : Arrays.stream(args);
//        List<Object> logArgs = stream
//                .filter(arg -> (!(arg instanceof HttpServletRequest) && !(arg instanceof HttpServletResponse)))
//                .collect(Collectors.toList());
//        //过滤后序列化无异常
//        String methodName = joinPoint.getSignature().getName();
//        logTemplate.setRequestRawJson(StringEscapeUtils.unescapeJavaScript(JSONObject.toJSONString(JSON.toJSONString(logArgs))));
//        logTemplate.setMethod(methodName);
//        logTemplate.setPath(joinPoint.getSignature().getDeclaringTypeName());
//
////        logJsonModel.set(logTemplate);
//        addLogData();
//        logger.info(logTemplate.toString());
        MDC.put("startTime", LocalDateTime.now().toString());
        MDC.put("endTime", LocalDateTime.now().toString());
        MDC.put("requestRawJson", "请求的：requestRawJson");
        MDC.put("responseRawJson","请求的：responseRawJson");
        MDC.put("responseTime", "请求的：responseTime");
        MDC.put("url", "菜市场上厕所测试测试从");
        MDC.put("method", joinPoint.getSignature().getName());
        MDC.put("path", joinPoint.getSignature().getDeclaringTypeName());
        logger.error("菜市场上厕所测试测试从");
    }

    /**
     * @Description:记录响应请求正常日志
     * @Param: [ret]
     * @Return: void
     */
    @AfterReturning(returning = "ret", pointcut = "webLog()")
    public void doAfterReturning(JoinPoint joinPoint,Object ret) throws Throwable {
        //过滤后序列化无异常
//        String methodName = joinPoint.getSignature().getName();
//        logJsonModel.get().setResponseRawJson(StringEscapeUtils.unescapeJavaScript(JSONObject.toJSONString(ret)));
//        logJsonModel.get().setResponseTime(System.currentTimeMillis() - logJsonModel.get().getResponseTime());
//        logJsonModel.get().setEndTime(LocalDateTime.now());


    }

    //自定义日志需要输入的字段
    private void addLogData() {

    }

    /**
     * @Description:记录响应请求异常日志
     * @Param: [ex]
     * @Return: void
     */
//    @AfterThrowing(throwing="ex",pointcut = "webLog()")
//    public void afterThrowing(Exception  ex) {
//        String errorCode = "";
//        String msg = "";
//        if (ex instanceof BusinessException) {
//            BusinessException be = (BusinessException)ex;
//            errorCode = be.getCode();
//            msg = be.getMessage();
//        } else if (ex instanceof MethodArgumentNotValidException) {
//            MethodArgumentNotValidException be = (MethodArgumentNotValidException)ex;
//            msg = be.getBindingResult().getAllErrors().stream()
//                    .map(DefaultMessageSourceResolvable::getDefaultMessage)
//                    .reduce((m1, m2) ->  m1 + ";" + m2)
//                    .orElse("未获取到错误信息");
//            errorCode = RespCode.FAILED.getCode();
//        }else {
//            errorCode = RespCode.FAILED.getCode();
//            msg = ex.getMessage();
//        }
////        logger.error("异常code:"+errorCode+",异常信息："+msg, e);
//        JSONObject repJson=new JSONObject();
//        repJson.put("errorCode",errorCode);
//        repJson.put("errorMsg",msg);
//        logJsonModel.get().setResponseRawJson(StringEscapeUtils.unescapeJavaScript(JSONObject.toJSONString(repJson)));
//        logJsonModel.get().setResponseTime(System.currentTimeMillis() - logJsonModel.get().getResponseTime());
//        logJsonModel.get().setEndTime(LocalDateTime.now());
//        logJsonModel.get().setMessage(msg);
//        addLogData();
////        logger.error("异常code:"+errorCode+",异常信息："+msg, ex);
//        logger.info(logJsonModel.get().toString());
//    }
}